const path = require("path");
const fs = require("fs");
const dayjs = require("dayjs");

/** 获取上传文件url */
module.exports.getUploadUrl = (addPath) => {
  return path.join(__dirname, "../../../uploads", addPath);
};

/**
 * 查找文件
 * @param {string} fileNamePath 文件路径
 * @returns {Array<string>}
 */
module.exports.findUploadFileList = (fileNamePath) => {
  const targetPath = module.exports.getUploadUrl("");

  // 查找 targetPath 文件夹中，文件名称包含 fileHash 的文件 （同步操作）
  const files = fs.readdirSync(targetPath);

  const findFileList = [];

  for (let i = 0; i < files.length; i++) {
    const file = files[i];
    if (file.includes(fileNamePath) && !file.includes("-chunk-")) {
      // return file;
      findFileList.push(file);
    }
  }

  return findFileList;
};

/**
 * 判断文件是否上传过
 * @param {string} fileHash
 */
module.exports.checkFileIsUploaded = (fileHash) => {
  const fileList = module.exports.findUploadFileList(`-${fileHash}-`);
  const isUpload = fileList.length > 0;
  return Promise.resolve(isUpload);
};

/**
 * 递归合并文件块的函数
 * @param {string} filename 文件名称
 * @param {string} fileHash 文件哈希值
 * @param {number} index chunk 的索引
 * @param {number} totalChunks 总的块数
 * @returns {Promise<string>}
 */
module.exports.mergeChunksMine = (
  filename,
  fileHash,
  index,
  totalChunks,
  successCallback
) => {
  const { getUploadUrl } = module.exports;

  // 生成合并后文件的存储路径
  const mergedPath = getUploadUrl(
    `${dayjs().format("YYYYMMDD-HHmmss")}-${fileHash}-${filename}`
  );

  // 创建写入合并后文件的可写流
  const writeStream = fs.createWriteStream(mergedPath);

  return mergeChunksItem(filename, fileHash, index + 1, totalChunks);

  function mergeChunksItem(filename, fileHash, index, totalChunks) {
    return new Promise((resolve, reject) => {
      // console.log(`[mergeChunks]: ${index}/${totalChunks}`);

      if (index - 1 === totalChunks) {
        try {
          writeStream.end(() => {
            console.log("合并完成");
            resolve("success");
            successCallback();
          }); // 所有块都合并完成后，关闭写入流
          return;
        } catch (error) {
          console.log(error, "writeStream end");
          reject(error);
        }
      }

      // 获取当前块的存储路径
      const chunkPath = getUploadUrl(
        `${filename}-${fileHash}-chunk-${index}-${totalChunks}`
      );

      // 同步读取当前块的内容
      const chunk = fs.readFileSync(chunkPath);

      // 删除已合并的块
      fs.unlinkSync(chunkPath);

      console.log(`${index}/${totalChunks}`);

      // 将块的内容写入合并后文件，并在写入完成后递归合并下一块
      // setTimeout(() => {
      writeStream.write(chunk, () => {
        mergeChunksItem(filename, fileHash, index + 1, totalChunks)
          .then(resolve)
          .catch(reject);
      });
      // }, 500);
    });
  }
};
